//
// Created by wxd on 2025/7/6.
// OpenGL错误状态检查类
//

#pragma once

#include "../../thirdParty/include/glad/glad.h"
#include <cassert>
#include <string>
#include <ostream>

#include "../../wrapper/log/Logger.h"
#include "../../utils/TimeUtils.hpp"

// 定义GL状态检查的宏
#ifdef GL_CHECK_DEBUG
#define GL_CALL(func) func; GLDebug::checkGL_Error(__FILE_NAME__, __FUNCTION__, __LINE__);
#else
#define GL_CALL(func) func;
#endif


namespace GLDebug {
    /**
     * OpenGL的错误码检查
     */
    inline void checkGL_Error(const char* file_name, const char* func_name, int func_line) {
        GLenum errorCode = glGetError();
        if (errorCode == GL_NO_ERROR) {
            return;
        }

        std::string error = "";

        switch(errorCode) {
            case GL_INVALID_ENUM:
                error = "(GL_INVALID_ENUM)枚举参数超出范围";
                break;
            case GL_INVALID_VALUE:
                error = "(GL_INVALID_VALUE)数值参数超出范围";
                break;
            case GL_INVALID_OPERATION:
                error = "(GL_INVALID_OPERATION)执行的命令不符合OpenGL规范";
            case GL_STACK_OVERFLOW:
                error = "(GL_STACK_OVERFLOW)函数调用导致堆栈溢出";
                break;
            case GL_STACK_UNDERFLOW:
                error = "(GL_STACK_UNDERFLOW)函数调用导致堆栈下溢";
                break;
            case GL_OUT_OF_MEMORY:
                error = "(GL_OUT_OF_MEMORY)内存不足，无法执行函数";
                break;
            default:
                break;
        }

        std::ostringstream oss;
        oss << "[" << EngineUtils::EngineTime::getInstance().getNow() << "]"
            << "[" << file_name << "]" << " "
            << "[" << func_name << "]" << " "
            << "[" << func_line << "]" << " "
            << error << "\n";

        // 这里oss.str()会返回std::string, 涉及字符串的拷贝，频繁调用会出现性能问题
        // std::cout << oss.str() << "\n"; // std::endl会强制刷新缓冲导致性能下降，手动换行即可
        printf("GL_ERROR_CHECK: %s", oss.str().data());

        assert(false);
    }
}

